package com.ruoyi.finance.szUser.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;


import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.pagehelper.util.StringUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.finance.livestreaming.entity.SzEnergyRecord;
import com.ruoyi.finance.livestreaming.entity.SzWalletDetail;
import com.ruoyi.finance.livestreaming.entity.SzWithdrawalDetail;
import com.ruoyi.finance.livestreaming.mapper.SzEnergyRecordMapper;
import com.ruoyi.finance.livestreaming.mapper.SzWalletDetailMapper;
import com.ruoyi.finance.livestreaming.mapper.SzWithdrawalDetailMapper;
import com.ruoyi.finance.protal.utils.UUID;
import com.ruoyi.finance.rules.entity.SzPromotionTree;
import com.ruoyi.finance.rules.mapper.SzPromotionTreeMapper;
import com.ruoyi.finance.rules.mapper.SzUserMapper;
import com.ruoyi.finance.szUser.domain.UserPasswordVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.finance.szUser.mapper.SzUserInfoMapper;
import com.ruoyi.finance.szUser.domain.SzUser;
import com.ruoyi.finance.szUser.service.SzUserInfoService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 平台用户Service业务层处理
 *
 * @author wangmh
 * @date 2023-10-07
 */
@Service
@Slf4j
public class SzUserInfoInfoServiceImpl implements SzUserInfoService
{
    @Autowired
    private SzUserInfoMapper szUserInfoMapper;

    @Autowired
    private SzUserMapper szUserMapper;

    @Autowired
    private SzPromotionTreeMapper szPromotionTreeMapper;

    @Autowired
    private SzWalletDetailMapper szWalletDetailMapper;

    @Autowired
    private SzWithdrawalDetailMapper szWithdrawalDetailMapper;

    @Autowired
    private SzEnergyRecordMapper szEnergyRecordMapper;

    @Value("${protal.defaulAvatar}")
    private  String defaulAvatar;

    @Value("${protal.defaultPassword}")
    private  String defaultPassword;

    @Value("${protal.defaultPaymentPassword}")
    private  String defaultPaymentPassword;

    /**
     * 查询平台用户
     *
     * @param id 平台用户主键
     * @return 平台用户
     */
    @Override
    public SzUser selectSzUserById(Long id)
    {
        return szUserInfoMapper.selectSzUserById(id);
    }

    /**
     * 查询平台用户列表
     *
     * @param szUser 平台用户
     * @return 平台用户
     */
    @Override
    public List<SzUser> selectSzUserList(SzUser szUser) {
        return szUserInfoMapper.selectSzUserList(szUser);
    }

    /**
     * 新增平台用户
     *
     * @param szUser 平台用户
     * @return 结果
     */
    @Override
    public AjaxResult insertSzUser(SzUser szUser) {
        // 校验手机号 身份证号 邀请码
        if (szUserMapper.selectCount(new LambdaQueryWrapper<com.ruoyi.finance.rules.entity.SzUser>()
                .eq(com.ruoyi.finance.rules.entity.SzUser::getPhone, szUser.getPhone())) != 0){
            return AjaxResult.error("该手机号已注册");
        }

        if (szUserMapper.selectCount(new LambdaQueryWrapper<com.ruoyi.finance.rules.entity.SzUser>()
                .eq(com.ruoyi.finance.rules.entity.SzUser::getIdNumber, szUser.getIdNumber())) != 0){
            return AjaxResult.error("该身份证号码已注册");
        }

        if (StringUtil.isNotEmpty(szUser.getInvitationParent())){
            if (szUserMapper.selectCount(new LambdaQueryWrapper<com.ruoyi.finance.rules.entity.SzUser>()
                    .eq(com.ruoyi.finance.rules.entity.SzUser::getInvitationCode, szUser.getInvitationParent())) == 0){
                return AjaxResult.error("邀请码错误");
            }
        }

        com.ruoyi.finance.rules.entity.SzUser user = new com.ruoyi.finance.rules.entity.SzUser();
        user.setNickname(szUser.getNickname());
        if (StringUtil.isEmpty(szUser.getAvatar())){
            user.setAvatar(defaulAvatar);
        }else{
            user.setAvatar(szUser.getAvatar());
        }
        user.setPhone(szUser.getPhone());
        user.setPassword(defaultPassword);
        user.setIdNumber(szUser.getIdNumber());
        user.setAccountType(szUser.getAccountType());
        user.setRegisterTime(LocalDateTime.now());
        user.setRecharge("0");
        user.setWithdrawalLimitMonth(BigDecimal.ZERO);
        user.setBaseGoldBalance(BigDecimal.ZERO);
        user.setWelfareGoldBalance(BigDecimal.ZERO);
        user.setWelfareWithdrawalBalance(BigDecimal.ZERO);
        user.setInvitationCode(this.getInvitationCode());
        user.setInvitationParent(szUser.getInvitationParent());
        user.setSzWalletBalance(BigDecimal.ZERO);
        user.setSzWithdrawalBalance(BigDecimal.ZERO);
        user.setSzTeamReward(BigDecimal.ZERO);
        user.setSzRangeReward(BigDecimal.ZERO);
        user.setSzLateralReward(BigDecimal.ZERO);
        user.setSzRepeatbuyReword(BigDecimal.ZERO);
        user.setSzEnergy(BigDecimal.ZERO);
        user.setSzEnable("0");
        user.setVoucher(BigDecimal.ZERO);
        user.setDeductionAmount(BigDecimal.ZERO);
        user.setFrozenAccount(BigDecimal.ZERO);
        user.setPendingActivationBalance(BigDecimal.ZERO);
        user.setIsSignOut("0");
        user.setIsFrozen("0");
        szUserMapper.insert(user);

        if (StringUtil.isNotEmpty(szUser.getInvitationParent())){
            SzPromotionTree tree = new SzPromotionTree();
            tree.setUserId(user.getId());
            tree.setParentId(szUserMapper.selectOne(new LambdaQueryWrapper<com.ruoyi.finance.rules.entity.SzUser>()
                    .eq(com.ruoyi.finance.rules.entity.SzUser::getInvitationCode, szUser.getInvitationParent()))
                    .getId());
            tree.setCreateTime(LocalDateTime.now());
            szPromotionTreeMapper.insert(tree);
        }

        return AjaxResult.success("操作成功");
    }

    // 注册时，生成一个随机邀请码
    private String getInvitationCode() {
        String invitationCode;
        Integer count;
        do {
            invitationCode = UUID.getInvitationCode();
            count = szUserMapper.selectCount(new LambdaQueryWrapper<com.ruoyi.finance.rules.entity.SzUser>().eq(com.ruoyi.finance.rules.entity.SzUser::getInvitationCode, invitationCode));
        } while (count > 0);

        return invitationCode;
    }

    /**
     * 修改平台用户
     *
     * @param szUser 平台用户
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult updateSzUser(SzUser szUser) {
        if (szUser.getFrozenAccount().compareTo(szUser.getSzWithdrawalBalance()) > 0){
            return AjaxResult.error("提现冻结金额不能大于可提现金额！");
        }

        Long userId = szUser.getId();
        Long oprationUser = SecurityUtils.getUserId();
        com.ruoyi.finance.rules.entity.SzUser updateUser = szUserMapper.selectById(userId);

        // 邀请人是否修改
        if (!Objects.equals(updateUser.getInvitationParent(), szUser.getInvitationParent())){
            if (StringUtil.isEmpty(szUser.getInvitationParent())){
                szPromotionTreeMapper.delete(new LambdaQueryWrapper<SzPromotionTree>().eq(SzPromotionTree::getUserId, userId));
                updateUser.setInvitationParent(null);
            }else{
                List<com.ruoyi.finance.rules.entity.SzUser> parentUser = szUserMapper.selectList(new LambdaQueryWrapper<com.ruoyi.finance.rules.entity.SzUser>()
                        .eq(com.ruoyi.finance.rules.entity.SzUser::getInvitationCode, szUser.getInvitationParent())
                        .eq(com.ruoyi.finance.rules.entity.SzUser::getIsSignOut, "0")
                        .eq(com.ruoyi.finance.rules.entity.SzUser::getDeleteFlag, "0"));

                if (parentUser.size() != 1){
                    return AjaxResult.error("邀请码错误，或此邀请码的用户已注销");
                }

                List<Map<String, Long>> trees = szUserMapper.selectUserJunior(userId);
                if (CollectionUtils.isNotEmpty(trees)){
                    if (trees.stream().map(map -> map.get("user_id")).anyMatch(parentUser.get(0).getId()::equals)){
                        return AjaxResult.error("修改失败，此用户已经是" + parentUser.get(0).getNickname() + "的上级或者间接上级！") ;
                    }
                }

                updateUserInvitation(szUser.getId(), parentUser.get(0).getId());
                updateUser.setInvitationParent(szUser.getInvitationParent());
            }
        }

        updateUser.setNickname(szUser.getNickname());
        updateUser.setAvatar(szUser.getAvatar());
        updateUser.setAccountType(szUser.getAccountType());
        updateUser.setIdNumber(szUser.getIdNumber());
        updateUser.setPhone(szUser.getPhone());

        if (updateUser.getSzWalletBalance().compareTo(szUser.getSzWalletBalance()) != 0) {
            BigDecimal diff = updateUser.getSzWalletBalance().subtract(szUser.getSzWalletBalance());
            BigDecimal absDiff = diff.abs(); // 获取差值的绝对值
            updateUser.setSzWalletBalance(szUser.getSzWalletBalance());

            if (diff.compareTo(BigDecimal.ZERO) > 0) {
                this.saveWalletDetail(userId, absDiff, "7", oprationUser);
            } else if (diff.compareTo(BigDecimal.ZERO) < 0) {
                this.saveWalletDetail(userId, absDiff, "6", oprationUser);
            }
        }

        if (updateUser.getSzWithdrawalBalance().compareTo(szUser.getSzWithdrawalBalance()) != 0) {
            BigDecimal diff = updateUser.getSzWithdrawalBalance().subtract(szUser.getSzWithdrawalBalance());
            BigDecimal absDiff = diff.abs(); // 获取差值的绝对值
            updateUser.setSzWithdrawalBalance(szUser.getSzWithdrawalBalance());

            if (diff.compareTo(BigDecimal.ZERO) > 0) {
                this.saveWithdrawalDetail(userId, absDiff, "7", oprationUser);
            } else if (diff.compareTo(BigDecimal.ZERO) < 0) {
                this.saveWithdrawalDetail(userId, absDiff, "6", oprationUser);
            }
        }

        if (updateUser.getSzEnergy().compareTo(szUser.getSzEnergy()) != 0) {
            BigDecimal diff = updateUser.getSzEnergy().subtract(szUser.getSzEnergy());
            BigDecimal absDiff = diff.abs(); // 获取差值的绝对值
            updateUser.setSzEnergy(szUser.getSzEnergy());

            if (diff.compareTo(BigDecimal.ZERO) > 0) {
                this.saveEnergyRecord(userId, absDiff, "7", oprationUser);
            } else if (diff.compareTo(BigDecimal.ZERO) < 0) {
                this.saveEnergyRecord(userId, absDiff, "6", oprationUser);
            }
        }

        if (updateUser.getFrozenAccount().compareTo(szUser.getFrozenAccount()) != 0){
            BigDecimal diff = updateUser.getFrozenAccount().subtract(szUser.getFrozenAccount());
            BigDecimal absDiff = diff.abs(); // 获取差值的绝对值
            updateUser.setFrozenAccount(szUser.getFrozenAccount());

            if (diff.compareTo(BigDecimal.ZERO) > 0) {
                this.saveWithdrawalDetail(userId, absDiff, "10", oprationUser);
            } else if (diff.compareTo(BigDecimal.ZERO) < 0) {
                this.saveWithdrawalDetail(userId, absDiff, "9", oprationUser);
            }
        }

        szUserMapper.updateById(updateUser);
        return AjaxResult.success();
    }

    private void updateUserInvitation(Long userId, Long parentId){
        szPromotionTreeMapper.delete(new LambdaQueryWrapper<SzPromotionTree>().eq(SzPromotionTree::getUserId, userId));
        SzPromotionTree promotionTree = new SzPromotionTree();
        promotionTree.setUserId(userId);
        promotionTree.setParentId(parentId);
        promotionTree.setCreateTime(LocalDateTime.now());
        szPromotionTreeMapper.insert(promotionTree);
    }

    private void saveWalletDetail(Long userId, BigDecimal money, String flowType, Long oprationUser){
        SzWalletDetail walletDetail = new SzWalletDetail();
        walletDetail.setUserId(userId);
        walletDetail.setMoney(money);
        walletDetail.setFlowType(flowType);
        walletDetail.setCreateUser(oprationUser);
        walletDetail.setCreateTime(LocalDateTime.now());
        szWalletDetailMapper.insert(walletDetail);
    }

    private void saveWithdrawalDetail(Long userId, BigDecimal money, String flowType, Long oprationUser){
        SzWithdrawalDetail withdrawalDetail = new SzWithdrawalDetail();
        withdrawalDetail.setUserId(userId);
        withdrawalDetail.setMoney(money);
        withdrawalDetail.setFlowType(flowType);
        withdrawalDetail.setCreateUser(oprationUser);
        withdrawalDetail.setCreateTime(LocalDateTime.now());
        szWithdrawalDetailMapper.insert(withdrawalDetail);
    }

    private void saveEnergyRecord(Long userId, BigDecimal energy, String flowType, Long oprationUser){
        SzEnergyRecord energyRecord = new SzEnergyRecord();
        energyRecord.setUserId(userId);
        energyRecord.setEnergy(energy);
        energyRecord.setType(flowType);
        energyRecord.setCreateUser(oprationUser);
        energyRecord.setCreateTime(LocalDateTime.now());
        szEnergyRecordMapper.insert(energyRecord);
    }

    /**
     * 批量删除平台用户
     *
     * @param ids 需要删除的平台用户主键
     * @return 结果
     */
    @Override
    public AjaxResult resetLoginPassword(Long[] ids) {
        if (ids.length>0){
            for (Long id : ids) {
                com.ruoyi.finance.rules.entity.SzUser user = szUserMapper.selectById(id);
                user.setPassword(defaultPassword);
                user.setLastUpdatePassword(LocalDateTime.now());
                szUserMapper.updateById(user);
            }
        }
        return AjaxResult.success();
    }


    /**
     * 删除平台用户信息
     *
     * @param id 平台用户主键
     * @return 结果
     */
    @Override
    public int deleteSzUserById(Long id)
    {
        return szUserInfoMapper.deleteSzUserById(id);
    }

    @Override
    public AjaxResult resetPaymentPassword(Long[] ids) {
        if (ids.length>0){
            for (Long id : ids) {
                com.ruoyi.finance.rules.entity.SzUser user = szUserMapper.selectById(id);
                user.setPaymentPassword(defaultPaymentPassword);
                szUserMapper.updateById(user);
            }
        }
        return AjaxResult.success();
    }

    /**
     * 修改平台用户支付密码
     * @param szUser
     * @return
     */
    @Override
    public AjaxResult editPaymentPassword(SzUser szUser) {
        return AjaxResult.success(szUserInfoMapper.updateSzUser(szUser));
    }

    @Override
    public AjaxResult logoutOrEnable(Long id, String type) {
        if (StringUtil.isEmpty(type) && !type.equals("1") && !type.equals("2") && id == null && id == 0L){
            return AjaxResult.error();
        }
        com.ruoyi.finance.rules.entity.SzUser user = szUserMapper.selectById(id);
        user.setIsSignOut(type);
        if (type.equals("1")){
            user.setSignOutTime(LocalDateTime.now());
        }
        szUserMapper.updateById(user);
       return AjaxResult.success();
    }

    @Override
    public AjaxResult delete(Long id, String type) {
        if (StringUtil.isEmpty(type) && !type.equals("1") && !type.equals("0") && id == null && id == 0L){
            return AjaxResult.error();
        }

        com.ruoyi.finance.rules.entity.SzUser user = szUserMapper.selectById(id);
        user.setDeleteFlag(type);
        if (type.equals("1")){
            user.setDeleteTime(LocalDateTime.now());
        }
        szUserMapper.updateById(user);
        return AjaxResult.success();
    }

    /**
     * 修改登录密码
     * @param vo
     * @return
     */
    @Override
    public AjaxResult editPassword(UserPasswordVO vo) {
        //校验旧密码是否正确
        Boolean result = checkPassword(vo);
        if (Objects.nonNull(result)){
            if (result){
                List<com.ruoyi.finance.rules.entity.SzUser> szUsers = findUserByPhone(vo.getPhone());
                if (CollUtil.isEmpty(szUsers)){
                    log.info(vo.getPhone()+"用户不存在");
                    return AjaxResult.error("用户不存在");
                }
                com.ruoyi.finance.rules.entity.SzUser szUser = szUsers.get(0);
                szUser.setPassword(vo.getNewPassword());
                szUserMapper.updateById(szUser);
                return AjaxResult.success("修改成功");
            }else{
                return AjaxResult.success("旧密码不正确");
            }
        }else{
            return AjaxResult.error("校验密码失败");
        }
    }

    /**
     * 校验手机号和密码是否匹配
     * @param vo
     * @return
     */
    @Override
    public Boolean checkPassword(UserPasswordVO vo){
        List<com.ruoyi.finance.rules.entity.SzUser> szUsers = findUserByPhone(vo.getPhone());
        if (CollUtil.isEmpty(szUsers)){
            log.info(vo.getPhone()+"用户不存在");
            return Boolean.FALSE;
        }
        log.info(vo.getPhone()+"结果："+szUsers.size());
        String password = szUsers.get(0).getPassword();
        if (vo.getPassword().equals(password)){
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * 根据手机号查询用户
     * @param phone
     * @return
     */
    @Override
    public List<com.ruoyi.finance.rules.entity.SzUser> selectUserByPhone(String phone) {
        return findUserByPhone(phone);
    }

    /**
     * 根据手机号查询用户
     * @param phone
     * @return
     */
    public List<com.ruoyi.finance.rules.entity.SzUser> findUserByPhone(String phone){
        List<com.ruoyi.finance.rules.entity.SzUser> szUsers;
        LambdaQueryWrapper<com.ruoyi.finance.rules.entity.SzUser> szUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        szUserLambdaQueryWrapper.eq(com.ruoyi.finance.rules.entity.SzUser::getPhone,phone);
        szUserLambdaQueryWrapper.eq(com.ruoyi.finance.rules.entity.SzUser::getDeleteFlag,"0");
        szUsers = szUserMapper.selectList(szUserLambdaQueryWrapper);
        return szUsers;
    }
}
